home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / IBMPC / MS_ANSI.C < prev    next >
C/C++ Source or Header  |  1992-12-08  |  6KB  |  323 lines

  1. /* ibmpc/ms_ansi.c: a set of routines to provide either PCcurses or ANSI output
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Don Kneller
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #include <curses.h>
  10. #include <stdio.h>
  11.  
  12. #if defined(MSDOS) && defined(ANSI)
  13.  
  14. #ifdef LINT_ARGS
  15. static int curses_move(int, int);
  16. static char *getent(char *,char * *,int );
  17. static void initansistr(void);
  18. static int ansi_initscr(void);
  19. static int ansi_endwin(void);
  20. static int ansi_addch(int );
  21. static int ansi_mvaddstr(int ,int ,char *);
  22. static int ansi_mvprintw(int ,int ,char *,int ,int ,int ,int );
  23. static int ansi_move(int ,int );
  24. static int ansi_move_tgoto(int ,int );
  25. static int ansi_clrtobot(void);
  26. static int ansi_clrtoeol(void);
  27. static int ansi_mvaddch(int ,int ,char );
  28. static int ansi_clear(void);
  29. static int ansi_refresh(void);
  30. static int ansi_noop(void);
  31. int ansi_prep(int ,int, int);
  32. #else
  33. static int    ansi_addch(), ansi_mvaddstr(), ansi_mvprintw(), ansi_move(),
  34.         ansi_move_tgoto(),
  35.         ansi_clrtobot(), ansi_clrtoeol(), ansi_mvaddch(), ansi_endwin(),
  36.         ansi_refresh(), ansi_clear(), ansi_noop(), ansi_initscr();
  37. int ansi_prep();
  38. #endif
  39.  
  40. extern char *tgetstr();
  41. extern char *getenv();
  42. extern char *tgoto();
  43.  
  44. /* Must supply a functional form of the PCcurses "move" routine */
  45. static int
  46. curses_move(y, x)
  47. int    y, x;
  48. {
  49.     return wmove(stdscr, y, x);
  50. }
  51.  
  52. /* Default is for curses to be used */
  53. int    (*output_addch)() = addch;
  54. int    (*output_mvaddstr)() = mvaddstr;
  55. int    (*output_mvprintw)() = mvprintw;
  56. int    (*output_move)() = curses_move;
  57. int    (*output_endwin)() = endwin;
  58. int    (*output_clrtobot)() = clrtobot;
  59. int    (*output_clrtoeol)() = clrtoeol;
  60. int    (*output_mvaddch)() = mvaddch;
  61. int    (*output_initscr)() = initscr;
  62. int    (*output_refresh)() = refresh;
  63. int    (*output_clear)() = clear;
  64.  
  65. int    (*output_nocrmode)() = nocrmode;
  66. int    (*output_crmode)() = crmode;
  67. int    (*output_nonl)() = nonl;
  68. int    (*output_nl)() = nl;
  69. int    (*output_noecho)() = noecho;
  70. int    (*output_echo)() = echo;
  71. int    ansi;
  72. int    LI;
  73.  
  74. #define LEFTFIELD    -10;
  75. #define    NEED        1
  76.  
  77. static int    moveopt = 1;
  78. static char    *CE, *CL, *CM, *DO, *LE, *ND, *TE, *TI, *UP;
  79. static int    currow = 0;
  80. static int    curcol = LEFTFIELD;
  81.  
  82. static char    *
  83. getent(str, tbufp, need)
  84. char    *str, **tbufp;
  85. int    need;
  86. {
  87.     char    *value;
  88.  
  89.     if ((value = tgetstr(str, tbufp)) == NULL && need == NEED)
  90.         error("termcap:  Moria needs %s\n", str);
  91.     return value;
  92. }
  93.  
  94. static void
  95. initansistr()
  96. {
  97.     static    char tbuf[512];
  98.     char    temp[1024], *tbufp, *term;
  99.  
  100.     if ((term = getenv("TERM")) == NULL)
  101.         term = "ibmpc-mono";
  102.     if (tgetent(temp, term) < 1)
  103.         error("Unknown terminal type: %s.", term);
  104.     tbufp = tbuf;
  105.     LE = getent("le", &tbufp, NEED);
  106.     CE = getent("ce", &tbufp, NEED);
  107.     CL = getent("cl", &tbufp, NEED);
  108.     CM = getent("cm", &tbufp, NEED);
  109.     ND = getent("nd", &tbufp, NEED);
  110.     TE = getent("te", &tbufp, !NEED);
  111.     TI = getent("ti", &tbufp, !NEED);
  112.     UP = getent("up", &tbufp, NEED);
  113.     DO = getent("do", &tbufp, NEED);
  114.     LI = tgetnum("li");
  115.     if (LI <= 0)
  116.         LI = 24;
  117. }
  118.  
  119. ansi_prep(check_ansi, domoveopt, truetgoto)
  120. int    check_ansi;
  121. int    domoveopt;
  122. int    truetgoto;
  123. {
  124.     moveopt = domoveopt;
  125.  
  126.     /* Check for ANSI.SYS */
  127.     if (check_ansi) {
  128.         /* Clear the input queue */
  129.         while (kbhit())
  130.             (void) getch();
  131.  
  132.         /* Send out the DSR string */
  133.         fputs("\033[6n", stdout);
  134.         fflush(stdout);
  135.  
  136.         /* Is there anything in the input?  If so ANSI responded. */
  137.         if (kbhit()) {
  138.             while (kbhit())
  139.                 (void) getch();
  140.         }
  141.         else {
  142.             putchar('\n');
  143.             error("ANSI.SYS not installed!  See MORIA.DOC for details!\n");
  144.         }
  145.     }
  146.  
  147.     /* get the ANSI strings */
  148.     initansistr();
  149.  
  150.     /* change function pointers to ANSI versions */
  151.     output_addch = ansi_addch;
  152.     output_mvaddstr = ansi_mvaddstr;
  153.     output_mvprintw = ansi_mvprintw;
  154.     if (truetgoto)
  155.         output_move = ansi_move_tgoto;
  156.     else
  157.         output_move = ansi_move;
  158.     output_clrtobot = ansi_clrtobot;
  159.     output_clrtoeol = ansi_clrtoeol;
  160.     output_mvaddch = ansi_mvaddch;
  161.     output_refresh = ansi_refresh;
  162.     output_clear = ansi_clear;
  163.     output_initscr = ansi_initscr;
  164.     output_endwin = ansi_endwin;
  165.  
  166.     output_nocrmode =
  167.     output_crmode =
  168.     output_nonl =
  169.     output_nl =
  170.     output_noecho =
  171.     output_echo = ansi_noop;
  172.  
  173.     ansi = 1;
  174. }
  175.  
  176. static int
  177. ansi_initscr()
  178. {
  179.     if (TI != NULL)
  180.         fputs(TI, stdout);
  181.     return OK;
  182. }
  183.  
  184. static int
  185. ansi_endwin()
  186. {
  187.     if (TI != NULL)
  188.         fputs(TE, stdout);
  189.     return OK;
  190. }
  191.  
  192. static int
  193. ansi_addch(ch)
  194. int    ch;
  195. {
  196.     putc(ch, stdout);
  197.     curcol++;
  198.     return OK;
  199. }
  200.  
  201. static int
  202. ansi_mvaddstr(row, col, str)
  203. int    row, col;
  204. char    *str;
  205. {
  206.     (void) ansi_move(row, col);
  207.     fputs(str, stdout);
  208.     curcol = LEFTFIELD;
  209.     return OK;
  210. }
  211.  
  212. static int
  213. ansi_mvprintw(row, col, fmt, a1, a2, a3, a4)
  214. int    row, col;
  215. char    *fmt;
  216. int    a1, a2, a3, a4;    /* large enough for %c%s%c of files.c ! */
  217. {
  218.     (void) ansi_move(row, col);
  219.     fprintf(stdout, fmt, a1, a2, a3, a4);
  220.     curcol = LEFTFIELD;
  221.     return OK;
  222. }
  223.  
  224. #define abs(x)    ((x) < 0 ? -(x) : (x))
  225.  
  226. /* For a bit more speed, don't use tgoto() from termcap */
  227. static int
  228. ansi_move(row, col)
  229. int    row, col;
  230. {
  231.     if (moveopt && abs(currow - row) < 3 && abs(curcol - col) < 3) {
  232.         while (row > currow)
  233.             fputs(DO, stdout), currow++;
  234.         while (row < currow)
  235.             fputs(UP, stdout), currow--;
  236.         while (col > curcol)
  237.             fputs(ND, stdout), curcol++;
  238.         while (col < curcol)
  239.             fputs(LE, stdout), curcol--;
  240.     }
  241.     else
  242.         fprintf(stdout, "\033[%d;%dH\0__cursor motion__", row+1,col+1);
  243.     currow = row;
  244.     curcol = col;
  245.     return OK;
  246. }
  247.  
  248. /* Use tgoto (which is rather slow) */
  249. static int
  250. ansi_move_tgoto(row, col)
  251. int    row, col;
  252. {
  253.     if (moveopt && abs(currow - row) < 3 && abs(curcol - col) < 3) {
  254.         while (row > currow)
  255.             fputs(DO, stdout), currow++;
  256.         while (row < currow)
  257.             fputs(UP, stdout), currow--;
  258.         while (col > curcol)
  259.             fputs(ND, stdout), curcol++;
  260.         while (col < curcol)
  261.             fputs(LE, stdout), curcol--;
  262.     }
  263.     else {
  264.         fputs(tgoto(CM, col, row), stdout);
  265.     }
  266.     currow = row;
  267.     curcol = col;
  268.     return OK;
  269. }
  270.  
  271. static int
  272. ansi_clrtobot()
  273. {
  274.     ansi_clrtoeol();
  275.     ansi_move(++currow, 0);
  276.     ansi_clrtoeol();
  277.     for (; currow <= LI; currow++) {
  278.         fputs(DO, stdout);
  279.         ansi_clrtoeol();
  280.     }
  281.     curcol = LEFTFIELD;
  282.     return OK;
  283. }
  284.  
  285. static int
  286. ansi_clrtoeol()
  287. {
  288.     fputs(CE, stdout);
  289.     return OK;
  290. }
  291.  
  292. static int
  293. ansi_mvaddch(row, col, ch)
  294. int    row, col;
  295. char    ch;
  296. {
  297.     ansi_move(row, col);
  298.     putchar(ch);
  299.     curcol++;
  300.     return OK;
  301. }
  302.  
  303. static int
  304. ansi_clear()
  305. {
  306.     fputs(CL, stdout);
  307.     return OK;
  308. }
  309.  
  310. static int
  311. ansi_refresh()
  312. {
  313.     fflush(stdout);
  314.     return OK;
  315. }
  316.  
  317. static int
  318. ansi_noop()
  319. {
  320.     return OK;
  321. }
  322. #endif
  323.